package com.feng.oauth2;

import com.feng.oauth2.oauth.domain.oauth.CustomJdbcTokenStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.vote.AffirmativeBased;
import org.springframework.security.access.vote.AuthenticatedVoter;
import org.springframework.security.access.vote.RoleVoter;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.authentication.BearerTokenExtractor;
import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler;
import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
import org.springframework.security.web.util.matcher.RequestMatcher;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

@Configuration
@EnableResourceServer
@Order(6)
public class MyResource extends ResourceServerConfigurerAdapter{

    @Autowired
    private CustomJdbcTokenStore customJdbcTokenStore;
//    @Autowired
//    private BearerTokenExtractor bearerTokenExtractor;
    @Autowired
    private DefaultTokenServices defaultTokenServices;
    @Autowired
    private OAuth2AuthenticationEntryPoint oAuth2AuthenticationEntryPoint;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId("default-resource").stateless(true).tokenStore(customJdbcTokenStore)
                .tokenServices(defaultTokenServices);
//                .tokenExtractor(bearerTokenExtractor);

    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
//        http.authorizeRequests().antMatchers("/test/test").hasRole("ROLE_USER")
//                .antMatchers("/test/test").access("#oauth2.hasScope('SCOPE_READ')" +
//                "and #oauth2.clientHasRole('ROLE_CLIENT' and hasRole('ROLE_USER'))");
//        http.authorizeRequests()
//                .antMatchers("/admin/**").hasRole("ADMIN")
//                .antMatchers("/user/**").hasAnyRole("ADMIN","USER")
//                .antMatchers("/test/test").hasRole("ROLE_USER").antMatchers("/test/test").access("#oauth2.hasScope('SCOPE_READ')")
               ;
               http.antMatcher("/api/**").authorizeRequests().anyRequest().permitAll();
               http.httpBasic().and().antMatcher("/test/**").antMatcher("/oauth/**").antMatcher("/api/**").authorizeRequests().and().formLogin().loginProcessingUrl("/api/login")
                       .passwordParameter("password").usernameParameter("username").permitAll().and().csrf().disable();
//               http.addFilterBefore()
    }

    @Bean
    public AccessDecisionManager accessDecisionManager() {
        List<AccessDecisionVoter<? extends Object>> decisionVoters = new ArrayList<>();
        decisionVoters.add(new RoleVoter());
        decisionVoters.add(new AuthenticatedVoter());
        decisionVoters.add(new RoleVoter());
        return new AffirmativeBased(decisionVoters);
    }

    public OAuth2AccessDeniedHandler oAuth2AccessDeniedHandler(){
        return new OAuth2AccessDeniedHandler();
    }


}